package org.apache.service.impl;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.dao.ContractDAO;
import org.apache.dao.EventDAO;
import org.apache.dto.Cookies;
import org.apache.model.Contract;
import org.apache.model.Event;
import org.apache.service.AbstractService;
import org.apache.service.ContractService;
import org.apache.util.Bet365;
import org.apache.util.CalcUtil;
import org.apache.util.StringUtil;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class ContractServiceImpl extends AbstractService implements ContractService, Bet365 {

    @Autowired
    private EventDAO eventDAO;

    @Autowired
    private ContractDAO contractDAO;

    @Override
    // production - backup
    public List<Contract> exposeContract(List<Event> events, Map<String, String> headers, Cookies cookies) {

        List<Contract> qualifyContracts = new ArrayList<Contract>();
        if (events != null && events.size() > 0) {
            System.out.println(":::::::::::::::::::::::::::");
            System.out.println(":::::::::::::::::::::::::::");
            System.out.println("::::::Start Contract:::::::");
            System.out.println(":::::::::::::::::::::::::::");
            System.out.println(":::::::::::::::::::::::::::");
            for (Event event : events) {
                try {
                    Document contractPage = redirectNavigator(event.getLocation(), headers, cookies);
                    if (hasAllMarkets(contractPage)) {
                        // get all markets link and update event DB
                        Element eAllMarketsLink = contractPage.select(ALL_MARKETS_CLASS + " a").get(0);
                        event.setLocation("../coupon/" + eAllMarketsLink.attr("href"));
                        eventDAO.update(event);
                        contractPage = redirectNavigator(event.getLocation(), headers, cookies);
                    }
                    Elements eContract = contractPage.select("a[href^=/AddToBetslip.aspx]");
                    Set<Contract> contracts = new HashSet<Contract>();
                    for (Element e : eContract) {
                        try {
                            // insert new or update exists
                            String contractStr = e.text();
                            String contractType = StringUtil.getContractType(contractStr);
                            Contract c = contractDAO.findByEventIdAndContractType(event.getId(), contractType);
                            if (c == null) {
                                c = new Contract();
                                contractDAO.insert(c);
                            }
                            c.setEvent(event);
                            c.setRate(CalcUtil.getRate(contractStr));
                            c.setContractType(contractType);
                            c.setQualify(isQualify(c.getRate()));
                            c.setBetSlipUrl(e.attr("href"));
                            contracts.add(c);
                            contractDAO.update(c);
                            System.out.println("--------");
                            System.out.println("Event: " + event.getName() + " - " + event.getPlayTime() + " - " + c.getContractType() + " - " + c.getRate()
                                    + " - Qualify : "
                                    + c.getQualify());
                            if (c.getQualify()) {
                                System.out.println(c.getBetSlipUrl());
                                qualifyContracts.add(c);
                            }
                            System.out.println("--------");
                        } catch (Exception e2) {
                            System.out.println("expose contract error : " + e.text());
                        }
                    }
                    if (contracts.size() > 0) {
                        event.setContracts(contracts);
                    }
                } catch (Exception e) {
                    System.out.println("Expose event error : " + event.getName());
                }
            }
            System.out.println(":::::::::::::::::::::::::::");
            System.out.println(":::::::::::::::::::::::::::");
            System.out.println("::::::End Contract:::::::");
            System.out.println(":: Total qualify contracts : " + qualifyContracts.size() + "  ::");
            System.out.println(":::::::::::::::::::::::::::");
        }
        return qualifyContracts;
    }

    // @Override
    // // development test
    // public List<Contract> exposeContract(List<Event> events, Map<String, String> headers, Cookies cookies) {
    //
    // List<Contract> qualifyContracts = new ArrayList<Contract>();
    // if (events != null && events.size() > 0) {
    // System.out.println(":::::::::::::::::::::::::::");
    // System.out.println(":::::::::::::::::::::::::::");
    // System.out.println("::::::Start Contract:::::::");
    // System.out.println(":::::::::::::::::::::::::::");
    // System.out.println(":::::::::::::::::::::::::::");
    // for (Event event : events) {
    // try {
    // Document contractPage = redirectNavigator(event.getLocation(), headers, cookies);
    // if (hasAllMarkets(contractPage)) {
    // // get all markets link and update event DB
    // Element eAllMarketsLink = contractPage.select(ALL_MARKETS_CLASS + " a").get(0);
    // event.setLocation("../coupon/" + eAllMarketsLink.attr("href"));
    // eventDAO.update(event);
    // contractPage = redirectNavigator(event.getLocation(), headers, cookies);
    // }
    // Elements eContract = contractPage.select("a[href^=/AddToBetslip.aspx]");
    // Set<Contract> contracts = new HashSet<Contract>();
    // for (Element e : eContract) {
    // try {
    // // insert new or update exists
    // String contractStr = e.text();
    // String contractType = StringUtil.getContractType(contractStr);
    // Contract c = contractDAO.findByEventIdAndContractType(event.getId(), contractType);
    // if (c == null) {
    // c = new Contract();
    // contractDAO.insert(c);
    // }
    // c.setEvent(event);
    // c.setRate(CalcUtil.getRate(contractStr));
    // c.setContractType(contractType);
    // c.setQualify(isQualify(c.getRate()));
    // c.setBetSlipUrl(e.attr("href"));
    // contracts.add(c);
    // contractDAO.update(c);
    // System.out.println("--------");
    // System.out.println("Event: " + event.getName() + " - " + event.getPlayTime() + " - " + c.getContractType() + " - " + c.getRate()
    // + " - Qualify : "
    // + c.getQualify());
    // if (c.getQualify()) {
    // System.out.println(c.getBetSlipUrl());
    // qualifyContracts.add(c);
    // }
    // System.out.println("--------");
    // } catch (Exception e2) {
    // System.out.println("expose contract error : " + e.text());
    // }
    // }
    // if (contracts.size() > 0) {
    // event.setContracts(contracts);
    // }
    // } catch (Exception e) {
    // System.out.println("Expose event error : " + event.getName());
    // }
    // }
    // System.out.println(":::::::::::::::::::::::::::");
    // System.out.println(":::::::::::::::::::::::::::");
    // System.out.println("::::::End Contract:::::::");
    // System.out.println(":: Total qualify contracts : " + qualifyContracts.size() + "  ::");
    // System.out.println(":::::::::::::::::::::::::::");
    // }
    // return qualifyContracts;
    // }

    // production
    private Boolean isQualify(Float rate) {

        return rate <= 1.02 && rate >= 1.01;
    }

    // // development
    // private Boolean isQualify(Float rate) {
    //
    // return rate <= 1.50;
    // }

    private boolean hasAllMarkets(Document contractPage) {

        try {
            return contractPage.select(ALL_MARKETS_CLASS).size() > 0;
        } catch (Exception e) {
        }
        return false;
    }

    @Override
    public Contract getRunningContract() {

        return contractDAO.getRunningContract();
    }

}
